import HttpClient from '../commons/http-client';
import {updateUser, userSignOut, UserType} from '../reducers/user';
import {updateToken} from '../reducers/token';
import {FormStatus, updateAppState} from '../reducers/app-state';
import AsyncStorage from '@react-native-async-storage/async-storage';
import DeviceInfo from 'react-native-device-info';
import Package from '../../package.json';
import moment from 'moment';
import {updateDevice} from '../reducers/device';
import {updateSignForm} from '../reducers/sign-form';
import Toast from '../components/toast';
import _ from 'lodash';
import Geolocation from '@react-native-community/geolocation';
import {search} from './search-actions';
import {loadOrders} from './order-actions';
import {loadMessages} from './message-actions';
import {I18n} from '../reducers/intl';

export function login(form) {
  return async dispatch => {
    try {
      const tokenRep = await HttpClient.post('/admin/auth/token', form);
      if (tokenRep.data.status !== 200) {
        throw new Error(tokenRep.data.err_msg);
      }
      const token = _.get(tokenRep, 'data.data.access', null);
      const type = _.get(tokenRep, 'data.data.user_type', null);
      HttpClient.setAuthToken(token);
      dispatch(updateToken({access: token}));
      await AsyncStorage.setItem('@token', token);
      await AsyncStorage.setItem('@type', type);
      await AsyncStorage.setItem('@username', form.username);
      await AsyncStorage.setItem('@password', form.password);
      dispatch(updateAppState({formStatus: FormStatus.SUCCESS}));
      dispatch(updateUser({type}));
      dispatch(fetchUserInfo());
      dispatch(loadOrders({}, 1));
      dispatch(loadMessages());
      dispatch(
        search({
          keywords: '',
          type: '',
          product: '',
          ordering: '',
          region: '',
          avail: '',
        }),
      );
    } catch (err) {
      Toast.show(I18n.t('toast.password'));
      throw err;
    }
  };
}

export function loadLocation() {
  return async (dispatch, getState) => {
    const {intl} = getState();
    /**
     {
      "coords": {
      "accuracy": 55.092132568359375,
          "altitude": 0,
          "heading": 0,
          "latitude": 30.633917,
          "longitude": 113.16945,
          "speed": 0
    },
      "mocked": false,
        "timestamp": 1624426497693
    }
     **/
    const localLocation = await AsyncStorage.getItem('@location');
    if (localLocation) {
      dispatch(
        updateAppState({
          location: JSON.parse(localLocation),
        }),
      );
    }
    Geolocation.setRNConfiguration({
      skipPermissionRequests: false,
      authorizationLevel: 'whenInUse',
    });
    Geolocation.getCurrentPosition(
      async info => {
        // const latitude = _.get(info, 'coords.latitude', 0);
        // const longitude = _.get(info, 'coords.longitude', 0);
        // dispatch(updateAddress(info.coords));
        dispatch(updateAppState({location: info.coords}));
      },
      error => {
        // console.log('error', JSON.stringify(error));
        if (error.message === 'Location permission was not granted.') {
          return Toast.show(I18n.t('toast.noPermission'));
        }
        Toast.show(error.message);
      },
    );
  };
}

export function fetchUserInfo() {
  return async (dispatch, getState) => {
    const {user} = getState();
    let userRep = {};
    let roleRep = {};
    try {
      // dispatch(updateAppState({loading: LoadingStatus.PENDING}));
      if (user.type === 'sysuser' || user.type === 'master') {
        userRep = await HttpClient.get('/admin/master/my');
        if (userRep.data.data.id !== 1) {
          roleRep = await HttpClient.get(
            `/admin/role/${userRep.data.data.role}`,
          );
          userRep.data.data.rolePerms = roleRep.data.data.perms;
        }
      } else {
        userRep = await HttpClient.get(
          `/web/${
            [UserType.dentist, UserType.clinic].includes(user.type)
              ? UserType.dentist
              : 'vend/vendor'
          }/basic_info`,
        );
      }
      dispatch(updateUser({...userRep.data.data}));
      // dispatch(updateAppState({loading: LoadingStatus.DONE}));
    } catch (e) {
      // dispatch(updateAppState({loading: LoadingStatus.ERROR}));
      throw e;
    }
  };
}

export function resetPassword(form) {
  return async dispatch => {
    const payload = {
      old_password: form.old_password,
      password: form.password,
    };
    try {
      dispatch(updateAppState({formStatus: FormStatus.PENDING}));
      // const loginRep = await HttpClient.post('admin/auth/token', payload);
      // const {access, user_type} = loginRep.data.data;
      dispatch(updateAppState({formStatus: FormStatus.SUCCESS}));
    } catch (e) {
      dispatch(updateAppState({formStatus: FormStatus.FAIL}));
      throw e;
    }
  };
}

export function changePassword(form) {
  return async (dispatch, getState) => {
    const {user} = getState();
    const payload = {
      old_password: form.oldPassword,
      password: form.newPassword,
    };
    try {
      dispatch(updateAppState({formStatus: FormStatus.PENDING}));
      const url =
        user.type === UserType.dentist
          ? '/web/dentist/reset_password'
          : '/web/vend/vendor/reset_password';
      const CPWRep = await HttpClient.put(url, payload);
      dispatch(updateAppState({formStatus: FormStatus.SUCCESS}));
    } catch (e) {
      dispatch(updateAppState({formStatus: FormStatus.FAIL}));
      throw e;
    }
  };
}

export function signOut() {
  return async dispatch => {
    dispatch(userSignOut());
    HttpClient.setAuthToken(null);
    await AsyncStorage.clear();
  };
}

export function setToken(token) {
  return dispatch => {
    dispatch(updateToken(token));
  };
}

export function setUserType(type) {
  return dispatch => {
    dispatch(updateUser({type}));
  };
}

export function loadToken() {
  return async dispatch => {
    try {
      const token = await AsyncStorage.getItem('@token');
      const type = await AsyncStorage.getItem('@type');
      if (!token) {
        return;
      }
      HttpClient.setAuthToken(token);
      dispatch(updateUser({type}));
      dispatch(updateToken({access: token}));
      dispatch(fetchUserInfo());
      dispatch(loadOrders({}, 1));
      dispatch(loadMessages());
    } catch (err) {}
  };
}

export function loadDeviceInfo() {
  return dispatch => {
    const deviceInfo = {
      appVersion: DeviceInfo.getReadableVersion(),
      jsVersion: Package.version,
      brand: DeviceInfo.getBrand(),
      osVersion: DeviceInfo.getDeviceId(),
      deviceId: DeviceInfo.getUniqueId(),
      timestamp: moment().valueOf(),
    };
    // HttpClient.post('/device', deviceInfo);
    dispatch(updateDevice(deviceInfo));
  };
}

export function update(payload) {
  return dispatch => {
    dispatch(updateSignForm(payload));
  };
}
